package org.oslims.client.uicomponents;

import java.util.Date;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.datepicker.client.DatePicker;

//Bug fixed when date value is null
public class EDatePickerCell extends AbstractCell<Date> {

	private static final int ESCAPE = 27;

	private final DatePicker datePicker;
	private final DateTimeFormat format;
	private int offsetX = 10;
	private int offsetY = 10;
	private PopupPanel panel;
	private ValueUpdater<Date> valueUpdater;

	@Override
	public boolean consumesEvents() {
		return true;
	}

	/**
	 * Constructs a new DatePickerCell that uses the date/time format given by
	 * {@link DateTimeFormat#getFullDateFormat}.
	 */
	public EDatePickerCell() {
		this(DateTimeFormat.getFullDateFormat());
	}

	/**
	 * Constructs a new DatePickerCell that uses the given date/time format.
	 */
	public EDatePickerCell(DateTimeFormat format) {
		this.format = format;

		this.datePicker = new DatePicker();
		this.panel = new PopupPanel(true, true) {
			@Override
			protected void onPreviewNativeEvent(NativePreviewEvent event) {
				if (Event.ONKEYUP == event.getTypeInt()) {
					if (event.getNativeEvent().getKeyCode() == ESCAPE) {
						// Dismiss when escape is pressed
						panel.hide();
					}
				}
			}
		};
		panel.add(datePicker);

		// Hide the panel and call valueUpdater.update when a date is selected
		datePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {
			public void onValueChange(ValueChangeEvent<Date> event) {
				panel.hide();
				valueUpdater.update(event.getValue());
			}
		});
	}

	@Override
	public Object onBrowserEvent(final Element parent, Date value, Object viewData, NativeEvent event, ValueUpdater<Date> valueUpdater) {
		if (event.getType().equals("click")) {

			this.valueUpdater = valueUpdater;

			if (value == null)
				value = new Date();

			datePicker.setCurrentMonth(value);
			datePicker.setValue(value);
			panel.setPopupPositionAndShow(new PositionCallback() {
				public void setPosition(int offsetWidth, int offsetHeight) {
					panel.setPopupPosition(parent.getAbsoluteLeft() + offsetX, parent.getAbsoluteTop() + offsetY);
				}
			});
		}
		return viewData;
	}

	@Override
	public void render(Date value, Object viewData, StringBuilder sb) {
		if (value != null) {
			sb.append(format.format(value));
		}
	}

}
